﻿using System;
using System.Linq;
using Microsoft.Practices.Unity;
using RG.Common;

namespace RG.Common.WPF.Workplaces
{

    // про Settings всё осталось в MultiWorkplaceConfig
    
    public class OneWorkplaceConfig
    {
        [Dependency]
        public IUnityContainer Cfg { get; set; }

        public FrameDescVM ResolveGroup(FrameDescVM parent, FrameGroup item)
        {
            var vm = new FrameDescVM(parent)
                         {Item = item, Name = item.Name, Config = new FrameConfigSettings {Id = item.GetType().GUID}};

            foreach (var desc in item.Childs)
            {
                var newVm = ResolveItem(vm, desc, null);
                vm.Childs.Add(newVm);
            }
            return vm;
        }

        private FrameDescVM ResolveSingle(TreeViewItemViewModel parent, FrameSingle item)
        {
            var vm = new FrameDescVM(parent)
                         {Item = item, Name = item.Name, Config = new FrameConfigSettings {Id = item.Type.GUID}};

            var settings = Cfg.Resolve<IFrameSettingsService>();
            settings.Init(item.Type);
            vm.SettingsService = settings;

            if (settings.SavedConfig.Count() > 0)
            {
                foreach (var cfg in settings.SavedConfig)
                {
                    var childVM = new FrameDescVM(vm) { Item = item, Name = cfg.Name, Config = cfg };
                    vm.Childs.Add(childVM);
                }
            }
            return vm;
        }

        public void SaveConfig(FrameDescVM fiVM, FrameConfigSettings fcs)
        {
            if (fiVM.Item is FrameGroup) return;
            var isNewConfig = true;
            var parFiVM = GetFiVMMaster(fiVM);
            foreach (var sc in parFiVM.SettingsService.SavedConfig)
            {
                if (sc.Id != fcs.Id) continue;
                isNewConfig = false; break;
            }
            if (isNewConfig)
            {// 
                var childVM = new FrameDescVM(parFiVM) { Item = fiVM.Item, Config = fcs };
                parFiVM.Childs.Add(childVM);
            }
            else
                fiVM.Config = fcs;
            parFiVM.SettingsService.Save(fcs);
        }

        /// <summary>
        /// Возвращаем FrameDescVM под которую будем вешать новые FrameDescVM с конфигами
        /// 
        /// </summary>
        /// <param name="fiVM"></param>
        /// <returns></returns>
        private static FrameDescVM GetFiVMMaster(FrameDescVM fiVM)
        {
            return ((FrameDescVM)fiVM.Parent).Item is FrameSingle ? (FrameDescVM)fiVM.Parent : fiVM;
        }

        public void DeleteFrameConfigSettingsForFiVM(FrameDescVM fiVM)
        {
            if (fiVM.Config == null) return;
            var parFiVM = (FrameDescVM)fiVM.Parent;
            if (parFiVM.SettingsService == null) return;
            parFiVM.Childs.Remove(fiVM);
            FrameConfigSettings fcsWithSameID = null;
            foreach (var sc in parFiVM.SettingsService.SavedConfig)
            {
                if (sc.Id != fiVM.Config.Id) continue;
                fcsWithSameID = sc;
                break;
            }
            fiVM.Config = null; //иначе потом если таб с ним открыт то она опять сохранится
            if (fcsWithSameID != null)
                parFiVM.SettingsService.Delete(fcsWithSameID);
        }

        protected FrameDescVM ResolveItem(FrameDescVM parent, FrameDesc child, FrameConfigSettings cfg)
        {
            if (child is FrameGroup)
                return ResolveGroup(parent, (FrameGroup)child);

            if (child is FrameSingle)
                return ResolveSingle(parent, (FrameSingle)child);

            throw new ApplicationException("Некорректные настройки");
        }
    }
}
